using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using server.Services;
using server.Models;
using server.Extensions;
namespace server.Controllers;

    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private LibraryContext db;
        private TokenService tokenService;
        public UserController(LibraryContext db, TokenService tokenService)
        {
            this.db = db;
            this.tokenService = tokenService;
        }
        private bool ValidateRoleName(string input){
            var role_names=new string[]{"reader","bookmanager","usermanager"};
            return role_names.Contains(input.ToLower());
        }
        [HttpGet("all")]
        [TypeFilter(typeof(TokenFilterAttribute), Arguments = new Object[]{Right.UserManager})]
        public async Task<IActionResult> GetAll(string? rolename)
        {
            if (rolename is null)
            {
                var all = await db.Users.Include(u=>u.Role).ToArrayAsync();
                return Ok(all.Select(u=>new UserResponse(u,u.Role.Name)));                
            }
            if (!ValidateRoleName(rolename))
            {
                return BadRequest("Invalid role name:"+rolename);
            }
            var role= await db.Roles.Where(r=>r.Name.ToLower()==rolename.ToLower()).FirstOrDefaultAsync();
            if (role is null)
            {
                return BadRequest("Invalid role name:"+rolename);                
            }
            var users= await db.Users.Where(u=>u.RoleID==role.ID).ToArrayAsync();
            return Ok(users.Select(u=>new UserResponse(u,role.Name)));
        }
        [HttpGet("{uid:int}")]
        [TypeFilter(typeof(TokenFilterAttribute), Arguments = new Object[]{Right.UserManager})]
        public async Task<IActionResult> Get(int uid)
        {
            var user = await db.Users.FindAsync(uid);
            if (user is null)
            {
                return NotFound();
            }
            return Ok(user);
        }
        [HttpGet("roles")]
        public async Task<IActionResult> GetRoleOptions()
        {
            var roles = await db.Roles.ToArrayAsync();
            var options = roles.Select(r => new FieldOption<int>(r.Name, r.ID)).ToArray();
            return Ok(options);
        }
        [HttpGet("add/template")]
        public IActionResult GetUserTemplate()
        {
            var template = Schema.GetSchema(typeof(NewUser));
            return Ok(template);
        }
        [TypeFilter(typeof(TokenFilterAttribute), Arguments = new Object[]{Right.UserManager})]
        [HttpPost("add")]
        public async Task<IActionResult> AddUser(NewUser new_user)
        {
            // System.Console.WriteLine("*********Add User Action");
            if (ModelState.IsValid == false)
            {
                return BadRequest(ModelState);
            }
            if (db.Users.Any(u => u.NickName == new_user.NickName))
            {
                return BadRequest($"用户昵称{new_user.NickName}已经被占用!");
            }
            // var next_uid = await db.Users.OrderByDescending(u => u.ID).Select(u => u.ID).FirstOrDefaultAsync() + 1;
            // System.Console.WriteLine("before insert new user");
            var user = new User(new_user, db);
            // Console.WriteLine(user.ToString());
            await db.Users.AddAsync(user);
            await db.SaveChangesAsync();
            return Ok(user);
        }
        [TypeFilter(typeof(TokenFilterAttribute), Arguments = new Object[]{Right.UserManager})]
        [HttpPost("import")]
        public async Task<IActionResult> ImportUsers(List<NewUser> new_users){
            System.Console.WriteLine("Import user action..");
            if (ModelState.IsValid == false)
            {
                return BadRequest(ModelState);
            }
            var repeated_nicknames=new List<string>();

            // foreach (var u in new_users)
            // {
            //     if (new_users.Any(u => u.NickName == u.NickName)){
            //         repeated_nicknames.Add(u.NickName);
            //     }
            // }
            var valid_roles=new string[]{
                "reader","bookmanager","usermanager"
            };
            foreach (var nu in new_users)
            {
                if (db.Users.Any(u => u.NickName == nu.NickName)){
                    repeated_nicknames.Add(nu.NickName);
                }
                if (!valid_roles.Contains(nu.Role.ToLower()))
                {
                    return BadRequest("Invalid Role: "+nu.Role);
                }
            }
            if (repeated_nicknames.Count>0)
            {
                return BadRequest("包含重复昵称:"+String.Join(",",repeated_nicknames));
            }
            await db.Users.AddRangeAsync(new_users.Select(u=>new User(u,db)));
            var count= await db.SaveChangesAsync();
            return Ok(new ImportResponse{
                AcceptCount=new_users.Count,
                RepeatCount=0,
                ImportCount=count,
            });
        }

    
    [TypeFilter(typeof(TokenFilterAttribute), Arguments = new Object[]{Right.UserManager})]
    [HttpDelete("delete/{uid:int}")]
    public async Task<IActionResult> DeleteUser(int uid){
        var user= await db.Users.FindAsync(uid);
        if (user is null)
        {
            return NotFound("Not found user with id:"+uid);
        }
        db.Users.Remove(user);
        await db.SaveChangesAsync();
        return Ok(user);
    }

    [HttpGet("check")]
    [TypeFilter(typeof(TokenFilterAttribute), Arguments = new Object[]{Right.None})]
    public IActionResult CheckLoginState(){
        return Ok();
    }
}

